package breadbox.dataManagement;

import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import breadbox.pastry.ID;
import breadbox.pastry.Message;

public abstract class Manager extends UnicastRemoteObject implements RMIMessage {

	protected Storage storage;
	protected RMIMessage client; 
	protected Registry registry;
	protected ReplicationManager repManager;
	protected boolean replicate;
	public Manager() throws IOException {
		super();
		client = null;
		replicate = false;
	}
	
	public void turnOnReplicate() {
		replicate = true;
	}
	
	//used so ReplcationManager can see if the Manager turned on replication
	public boolean isReplicating() {
		return replicate;
	}
	
	//this method is called by the client to get,put,or delete a chunk
	public abstract void sendMessage(Message m);
	
	//routes a message
	public abstract int route(Message m);
	
	public Storage getStorage() {
		return storage;
	}
	
	//will attempt to initialize the client
	//returns true if it is a client message 
	public void initializeClient(Message m) {
		try {
			client = (RMIMessage)registry.lookup("RMIMessageReceiver");
			System.out.println("got new client");
		}
		catch(Exception e) {
			System.err.println("could not lookup the RMIMessageReceiver");
		}
	}
	
	public void startRMI() throws Exception{
		int port = 1112;
	    try {
	    	System.err.println("creating registry");
	    	registry = LocateRegistry.createRegistry(port);
	    	registry.bind("pastryServer", this);
	    }
	    catch(RemoteException r) {
	    	System.err.println("registry already exists");
	    	registry = LocateRegistry.getRegistry(port);
	    	registry.rebind("pastryServer", this);
	    }
	}
	
	public void startReplication() {
		turnOnReplicate();
		repManager.run();
	}
}
